#include "hexstringconvert.h"
#include <sstream>

std::string hexstringconvert::hex2string(char *pHex, int nLen)
{
	unsigned char Nibble[2];
	std::string returnString = "";

	if (NULL == pHex || 0 == nLen)
	{
		std::cout << "Parameter error!!! " << "pHex: " << pHex << "nLen: " << nLen << std::endl;
		return "";
	}

	for (int i = 0; i < nLen; i++)
	{
		Nibble[0] = (pHex[i] & 0xF0) >> 4;
		Nibble[1] = pHex[i] & 0x0F;
		for (int j = 0; j < 2; j++)
		{
			if (Nibble[j] < 10)
				Nibble[j] += 0x30;
			else
			{
				if (Nibble[j] < 16)
					Nibble[j] = Nibble[j] - 10 + 'A';
			}
			returnString += Nibble[j];
		}   // for (int j = ...)
	}   // for (int i = ...)

	return returnString;
}

int hexstringconvert::hexfile2stringfile(const char *hexfilepath, const char *stringfilepath)
{
	if (NULL == hexfilepath || NULL == stringfilepath)
	{
		std::cout << "Parameter input error!!!" << "hexfilepath: " << hexfilepath << "stringfilepath" << stringfilepath << std::endl;
		return -1;
	}

	std::string inFileName = hexfilepath;
	std::string outFileName = stringfilepath;
	std::string fileString = "";

	std::ifstream infile(inFileName.c_str(), std::ifstream::binary);
	if (!infile.is_open())
	{
		std::cout << "File " << inFileName << " open failed!" << std::endl;
		return -1;
	}

	infile.seekg(0, infile.end);
	std::ios::pos_type srcSize = infile.tellg();
	infile.seekg(0);
	char *data = new char[srcSize];
	if (NULL == data)
	{
		std::cout << "Memory allocate failed!!" << std::endl;
		infile.close();
		return -1;
	}

	infile.read((char*)data, srcSize);
	fileString += this->hex2string(data, srcSize);
	infile.close();
	delete data;

	std::ofstream outfile(outFileName.c_str(), std::ios::trunc | std::ofstream::binary | std::ios::out);
	if (!outfile.is_open())
	{
		std::cout << "File " << outFileName << " open failed!" << std::endl;
		return -1;
	}
	outfile << fileString << std::endl;
	outfile.close();

	return 0;
}

//transfer string to hex-string 
std::string hexstringconvert::hex2hextabl(unsigned char* hex, int length)
{
	int cnt = 0;
	std::string temp1 = "0x";
	std::string temp2 = ",";
	std::string temp3 = "\r\n";
	std::ostringstream oss;

	oss.clear();
	while (length--)
	{
		oss << temp1;
		oss.fill('0');
		oss.width(2);
		oss << std::hex << int(*hex++);
		oss << temp2;
		if (0 == (++cnt % 16))
		{
			oss << temp3;
		}
		oss.clear();
	}
	return oss.str();
}

int hexstringconvert::hex2hextablfile(const char *hexfilepath, const char *stringfilepath)
{
	if (NULL == hexfilepath || NULL == stringfilepath)
	{
		std::cout << "Parameter input error!!!" << "hexfilepath: " << hexfilepath << "stringfilepath" << stringfilepath << std::endl;
		return -1;
	}

	std::string inFileName = hexfilepath;
	std::string outFileName = stringfilepath;
	std::string fileString = "";
	std::string outputFileString = "";

	std::ifstream infile(inFileName.c_str(), std::ifstream::binary);
	if (!infile.is_open())
	{
		std::cout << "File " << inFileName << " open failed!" << std::endl;
		return -1;
	}

	infile.seekg(0, infile.end);
	std::ios::pos_type srcSize = infile.tellg();
	infile.seekg(0);
	unsigned char *data = new unsigned char[srcSize];
	if (NULL == data)
	{
		std::cout << "Memory allocate failed!!" << std::endl;
		infile.close();
		return -1;
	}

	infile.read((char*)data, srcSize);
	fileString += this->hex2hextabl(data, srcSize);
	infile.close();
	delete data;

	outputFileString += "const unsigned char table[";
	std::ostringstream os;
	int length = fileString.length();
	length /= 5;
	os << length;
	outputFileString += os.str();
	os.clear();
	outputFileString += "] = \r\n{\r\n";
	outputFileString += fileString;
	outputFileString += "\r\n};";
	std::ofstream outfile(outFileName.c_str(), std::ios::trunc | std::ofstream::binary | std::ios::out);
	if (!outfile.is_open())
	{
		std::cout << "File " << outFileName << " open failed!" << std::endl;
		return -1;
	}
	outfile << outputFileString << std::endl;
	outfile.close();

	return 0;
}